#!/usr/bin/env python3
"""
提取IFC文件中所有门和窗的尺寸信息
"""

import ifcopenshell
import os
import json
from typing import Dict, List, Any

def extract_dimensions():
    """提取所有门和窗的尺寸信息"""
    
    # 查找IFC文件
    ifc_file_path = None
    
    # 检查当前目录
    ifc_files = [f for f in os.listdir('.') if f.endswith('.ifc')]
    if ifc_files:
        ifc_file_path = ifc_files[0]
    else:
        # 检查data/input目录
        data_input = os.path.join('data', 'input')
        if os.path.exists(data_input):
            ifc_files = [f for f in os.listdir(data_input) if f.endswith('.ifc')]
            if ifc_files:
                ifc_file_path = os.path.join(data_input, ifc_files[0])
    
    if not ifc_file_path:
        print("❌ 未找到IFC文件")
        return
    
    print(f"📂 正在加载IFC文件: {ifc_file_path}")
    
    try:
        ifc_file = ifcopenshell.open(ifc_file_path)
    except Exception as e:
        print(f"❌ 加载IFC文件失败: {e}")
        return
    
    # 提取所有门和窗
    doors = ifc_file.by_type("IfcDoor")
    windows = ifc_file.by_type("IfcWindow")
    
    print(f"🔍 找到 {len(doors)} 个门和 {len(windows)} 个窗")
    
    results = {
        "doors": [],
        "windows": [],
        "summary": {
            "total_doors": len(doors),
            "total_windows": len(windows),
            "doors_with_dimensions": 0,
            "windows_with_dimensions": 0
        }
    }
    
    def get_dimensions_from_element(element) -> Dict[str, Any]:
        """从元素中提取尺寸信息"""
        dimensions = {}
        
        # 检查基本属性
        size_attrs = ['OverallHeight', 'OverallWidth', 'Height', 'Width', 'Depth', 'Size']
        for attr in size_attrs:
            if hasattr(element, attr):
                value = getattr(element, attr)
                if value is not None:
                    dimensions[attr] = float(value) if isinstance(value, (int, float)) else str(value)
        
        # 检查类型属性
        if hasattr(element, 'IsDefinedBy'):
            for rel in element.IsDefinedBy:
                if rel.is_a('IfcRelDefinesByType'):
                    door_type = rel.RelatingType
                    if hasattr(door_type, 'HasPropertySets'):
                        for prop_set in door_type.HasPropertySets:
                            if prop_set.is_a('IfcDoorLiningProperties'):
                                if hasattr(prop_set, 'LiningDepth') and prop_set.LiningDepth:
                                    dimensions['LiningDepth'] = float(prop_set.LiningDepth)
                                if hasattr(prop_set, 'LiningThickness') and prop_set.LiningThickness:
                                    dimensions['LiningThickness'] = float(prop_set.LiningThickness)
                            elif prop_set.is_a('IfcDoorPanelProperties'):
                                if hasattr(prop_set, 'PanelWidth') and prop_set.PanelWidth:
                                    dimensions['PanelWidth'] = float(prop_set.PanelWidth)
                            elif prop_set.is_a('IfcWindowLiningProperties'):
                                if hasattr(prop_set, 'LiningDepth') and prop_set.LiningDepth:
                                    dimensions['LiningDepth'] = float(prop_set.LiningDepth)
                                if hasattr(prop_set, 'LiningThickness') and prop_set.LiningThickness:
                                    dimensions['LiningThickness'] = float(prop_set.LiningThickness)
                            elif prop_set.is_a('IfcWindowPanelProperties'):
                                if hasattr(prop_set, 'PanelWidth') and prop_set.PanelWidth:
                                    dimensions['PanelWidth'] = float(prop_set.PanelWidth)
                            elif prop_set.is_a('IfcPropertySet'):
                                for prop in prop_set.HasProperties:
                                    if hasattr(prop, 'NominalValue') and prop.NominalValue:
                                        prop_name = prop.Name
                                        prop_value = prop.NominalValue.wrappedValue
                                        if any(keyword in prop_name.lower() for keyword in ['height', 'width', 'depth', 'thickness', 'size']):
                                            dimensions[prop_name] = float(prop_value) if isinstance(prop_value, (int, float)) else str(prop_value)
        
        # 检查数量属性
        if hasattr(element, 'IsDefinedBy'):
            for rel in element.IsDefinedBy:
                if rel.is_a('IfcRelDefinesByProperties'):
                    prop_set = rel.RelatingPropertyDefinition
                    if prop_set.is_a('IfcElementQuantity'):
                        for quantity in prop_set.Quantities:
                            if hasattr(quantity, 'LengthValue') and quantity.LengthValue:
                                dimensions[quantity.Name] = float(quantity.LengthValue)
                            elif hasattr(quantity, 'AreaValue') and quantity.AreaValue:
                                dimensions[quantity.Name] = float(quantity.AreaValue)
                            elif hasattr(quantity, 'VolumeValue') and quantity.VolumeValue:
                                dimensions[quantity.Name] = float(quantity.VolumeValue)
        
        return dimensions
    
    # 处理门
    for door in doors:
        dimensions = get_dimensions_from_element(door)
        door_info = {
            "name": door.Name if door.Name else "未命名",
            "global_id": door.GlobalId,
            "object_type": door.ObjectType if door.ObjectType else None,
            "dimensions": dimensions,
            "has_dimensions": len(dimensions) > 0
        }
        
        if door_info["has_dimensions"]:
            results["summary"]["doors_with_dimensions"] += 1
        
        results["doors"].append(door_info)
    
    # 处理窗
    for window in windows:
        dimensions = get_dimensions_from_element(window)
        window_info = {
            "name": window.Name if window.Name else "未命名",
            "global_id": window.GlobalId,
            "object_type": window.ObjectType if window.ObjectType else None,
            "dimensions": dimensions,
            "has_dimensions": len(dimensions) > 0
        }
        
        if window_info["has_dimensions"]:
            results["summary"]["windows_with_dimensions"] += 1
        
        results["windows"].append(window_info)
    
    # 保存结果到JSON文件
    output_file = "extracted_dimensions.json"
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(results, f, ensure_ascii=False, indent=2)
    
    # 打印摘要
    print(f"\n📊 提取结果摘要:")
    print(f"门总数: {results['summary']['total_doors']}")
    print(f"有尺寸的门: {results['summary']['doors_with_dimensions']}")
    print(f"窗总数: {results['summary']['total_windows']}")
    print(f"有尺寸的窗: {results['summary']['windows_with_dimensions']}")
    
    # 显示前几个有尺寸的门和窗
    print(f"\n🚪 有尺寸的门示例:")
    doors_with_dims = [d for d in results['doors'] if d['has_dimensions']]
    for door in doors_with_dims[:3]:
        print(f"  {door['name']}: {door['dimensions']}")
    
    print(f"\n🪟 有尺寸的窗示例:")
    windows_with_dims = [w for w in results['windows'] if w['has_dimensions']]
    for window in windows_with_dims[:3]:
        print(f"  {window['name']}: {window['dimensions']}")
    
    print(f"\n💾 完整结果已保存到: {output_file}")

if __name__ == "__main__":
    extract_dimensions()